using System;
using OhioState.Math;

namespace OhioState.Graphics.Proxy
{

    //[Serializable()]
    //public class ROIBox : ROIBase
    //{
    //    // The permutation of the vertex index on the box
    //    // the vertex order is as follows.  0123 is back face and 4567 is front face
    //    //
    //    //       Y
    //    //       |
    //    //       3------2
    //    //      /|     /|
    //    //     / |    / |
    //    //    7------6  |
    //    //    |  |   |  |
    //    //    |  0---|--1-->X
    //    //    | /    | /
    //    //    |/     |/
    //    //    4------5
    //    //   /
    //    //  Z

    //    //
    //    // the array of box vertices, the index is as above
    //    //
    //    private BoxVertex[] m_BoxVertex;
    //    private ActiveEdgeList m_ActiveEdgeList;
    //    //
    //    // access matrix for the edges. The edges are defined by the adjacent matrix of the vertices.
    //    //
    //    private int[,] m_EdgeAccessFlag;
    //    //
    //    // the index of the nearest vertex where slice begins
    //    //
    //    private int m_NearestVertexID;
    //    //
    //    // the index of the farthest vertex where slice ends
    //    //
    //    private int m_FarthestVertexID;
    //    //
    //    // the current slice geometry
    //    //
    //    protected PolySlice m_pCurSlice;

    //    //
    //    // Main constructor
    //    //
    //    public ROIBox(String name)
    //        : base(name)
    //    {
    //        m_BoxVertex = new BoxVertex[8];
    //        for (int i = 0; i < m_BoxVertex.Length; i++)
    //        {
    //            m_BoxVertex[i] = new BoxVertex();
    //            m_BoxVertex[i]._Neighbor[0] = new Neighbor();
    //            m_BoxVertex[i]._Neighbor[1] = new Neighbor();
    //            m_BoxVertex[i]._Neighbor[2] = new Neighbor();
    //        }
    //        m_ActiveEdgeList = new ActiveEdgeList();
    //        m_EdgeAccessFlag = new int[8, 8];
    //        m_pCurSlice = new PolySlice();
    //        m_pCurSlice.NumVertices = 0;
    //        m_pCurSlice.Vertices = new Vector3[6];
    //    }

    //    public ROIBox(String name, BoundingBox boundingBox)
    //        : base(name, boundingBox)
    //    {
    //        m_BoxVertex = new BoxVertex[8];
    //        for (int i = 0; i < m_BoxVertex.Length; i++)
    //        {
    //            m_BoxVertex[i] = new BoxVertex();
    //            m_BoxVertex[i]._Neighbor[0] = new Neighbor();
    //            m_BoxVertex[i]._Neighbor[1] = new Neighbor();
    //            m_BoxVertex[i]._Neighbor[2] = new Neighbor();
    //        }
    //        m_ActiveEdgeList = new ActiveEdgeList();
    //        m_EdgeAccessFlag = new int[8, 8];
    //        m_pCurSlice = new PolySlice();
    //        m_pCurSlice.NumVertices = 0;
    //        m_pCurSlice.Vertices = new Vector3[6];
    //    }

    //    #region property
    //    public PolySlice CurrentSlice
    //    {
    //        get { return m_pCurSlice; }
    //        set { m_pCurSlice = value; }
    //    }
    //    public BoxVertex[] BoxVertex
    //    {
    //        get { return m_BoxVertex; }
    //        set { m_BoxVertex = value; }
    //    }

    //    public int NearestVertexID
    //    {
    //        get { return m_NearestVertexID; }
    //        set { m_NearestVertexID = value; }
    //    }

    //    public int FarthestVertexID
    //    {
    //        get { return m_FarthestVertexID; }
    //        set { m_FarthestVertexID = value; }
    //    }

    //    public int[,] EdgeAccessFlag
    //    {
    //        get { return m_EdgeAccessFlag; }
    //        set { m_EdgeAccessFlag = value; }
    //    }

    //    public ActiveEdgeList ActiveEdgeList
    //    {
    //        get { return m_ActiveEdgeList; ;}
    //        set { m_ActiveEdgeList = value; }
    //    }
    //    #endregion

    //    #region private methods
    //    #endregion

    //    //
    //    // Clone - make a duplicate copy of this object and return it
    //    //
    //    public override Object Clone()
    //    {
    //        BoundingBox boundaryBox = bBox as OhioStateCommon.BoundingBox;
    //        ROIBox roi = new ROIBox(Name, (BoundingBox)boundaryBox.Clone());
    //        roi.SliceThickness = sliceThickness;
    //        roi.Boundary = (Boundary)boundary.Clone();
    //        roi.Outline = (Outline)outline.Clone();
    //        roi.ShowOutline = showOutline;
    //        roi.ShowBoundary = showBoundary;
    //        // Dupe clip planes
    //        foreach (Vector4 vec in clipPlanes)
    //        {
    //            roi.clipPlanes.Add(new Vector4(vec.x, vec.y, vec.z, vec.w));
    //        }
    //        // Drawable duplicate
    //        MaterialProxy newMaterial = (MaterialProxy)_material.Clone();
    //        this.Material = newMaterial;
    //        //roi._material = (MaterialProxy) this._material.Clone();
    //        //this._material.CloneUVVs(roi.Material.Shader.GetUniformVariables() ); //roi.UniformVariableValues);

    //        return roi;
    //    }
    //}

    [Serializable()]
    public class Neighbor
	{
        //
        // the vertex's neighbor index
        //
		private int id;	            
		private Vector3 edge_dir;   
        //
        // theta is the angle between the slice inverse normal and the edge direction
        //
		private float cos_theta;	

		public Neighbor()
		{
			id = 0;
			edge_dir = new Vector3();
			cos_theta = 0.0f;
		}

        #region public property
		public int ID
		{
			get { return this.id; }
			set { this.id = value; }
		}

		public Vector3 Edge_dir
		{
			get { return this.edge_dir; }
		}

		public float Cos_theta
		{
			get { return this.cos_theta; }
			set { this.cos_theta = value; }
		}
        #endregion
	}


    [Serializable()]
    public class BoxVertex
	{
        //
        // the vertex id on the ROI Box
        //
		private int id;						
        //
        // the vertex id on the ROI Box
        //
		private Vector3 pos = new Vector3();
		private Neighbor[] _neighbor;

		public BoxVertex()
		{
			id = 0;
			pos.Zero();
			_neighbor = new Neighbor[3];
		}

        #region public property
		public int ID
		{
			get { return this.id;}
			set { this.id = value; }
		}
     
		public Vector3 Pos
		{
			get { return this.pos; }
			set { this.pos = value; }
		}

		public Neighbor[] _Neighbor
		{
			get { return this._neighbor; }
		}
        #endregion
	}

    [Serializable()]
    public class ActiveEdge
	{
        //
		// vertex_id[0] is the index of start point of the edge in m_BoxVertex; ; 
		// vertex_id[1] is the index of end point of the edge in m_BoxVertex;
        //
		private int[] vertex_id;   
        //
		// theta is the angle between the edge and the slice inverse normal 
        //
		private float cos_theta;		       
        //
		// length from the start point to end point of the edge
        //
		private float length;			       
        //
		// the current length from the start vertex
        //
		private float sum_delta;		       
        //
		// whether have computed the advance for the current slice along this edge
        //
		private	bool is_computed;              

		public ActiveEdge()
		{
			this.vertex_id = new int[2];
			this.cos_theta = 0.0f;
			this.length = 0.0f;
			this.sum_delta = 0.0f;
			this.is_computed = false;
		}

        #region public property
		public int[] Vertex_id
		{
			get { return this.vertex_id; }
			set { this.vertex_id = value; }
		}

		public float Cos_theta
		{
			get { return this.cos_theta; }
			set { this.cos_theta = value; }
		}

		public float Length
		{
			get { return this.length; }
			set { this.length = value; }
		}

		public float Sum_delta
		{
			get { return this.sum_delta; }
			set { this.sum_delta = value; }
		}

		public bool Is_computed
		{
			get { return this.is_computed; }
			set { this.is_computed = value; }
		}
        #endregion
	}

    [Serializable()]
    public class ActiveEdgeList
	{
        //
		// the number of edges in the list
        //
		private int numEdges;			  
   
        //
		// the active edge for the intersected slice is no more than 12 (for a box)
        //
		private ActiveEdge[] active_edge; 

		public ActiveEdgeList()
		{
			numEdges = 0;
			active_edge = new ActiveEdge[12];
		}

        #region public property
		public int NumEdges
		{
			get { return this.numEdges; }
			set { this.numEdges = value; }
		}

		public ActiveEdge[] Active_edge
		{
			get { return this.active_edge;}
		}
        #endregion
	}
}
